package com.yt.calendar.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yt.calendar.constant.CalendarConstant;
import com.yt.calendar.dto.EventDto;
import com.yt.calendar.entity.Config;
import com.yt.calendar.entity.Event;
import com.yt.calendar.entity.Plan;
import com.yt.calendar.mapper.EventMapper;
import com.yt.calendar.service.IConfigService;
import com.yt.calendar.service.IEventService;
import com.yt.calendar.service.IPlanService;
import com.yt.calendar.vo.EventVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yt
 * @since 2021-07-16
 */
@Service
public class EventServiceImpl extends ServiceImpl<EventMapper, Event> implements IEventService {
    @Resource
    private EventMapper eventMapper;
    @Resource
    private IPlanService iPlanService;
    @Resource
    private IConfigService iConfigService;

    @Override
    public List<EventVo> listByDate(LocalDate startDate, LocalDate endDate) {
        QueryWrapper<EventVo> wrapper = new QueryWrapper<>();
        wrapper.ge("e.day", startDate).le("e.day", endDate);
        return eventMapper.selectBy(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean savePlanAndEvent(EventDto eventDto) {
        // 保存plan
        int planId = savePlan(eventDto);

        // 原始日期
        LocalDate oriDate = LocalDateTimeUtil.parseDate(eventDto.getDay(), "yyyyMMdd");

        // 获取所有日期
        List<LocalDate> dateList = getAllDateList(oriDate);

        // 添加event
        List<Event> eventList = new ArrayList<>();
        for (LocalDate date : dateList) {
            Event event = new Event();
            event.setDay(date);
            event.setPlanId(planId);
            event.setColor(eventDto.getColor());
            event.setStatus(CalendarConstant.STATUS_UNFINISHED);
            event.setIsOriginal(oriDate.equals(date) ? 1 : 0);
            eventList.add(event);
        }
        return this.saveBatch(eventList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removePlanAndEvent(EventDto eventDto) {
        if (eventDto == null || eventDto.getIsOriginal() == null || eventDto.getPlanId() == null || eventDto.getEventId() == null) {
            return false;
        }

        // 原始删全部，非原始删单个
        if (1 == eventDto.getIsOriginal()) {
            UpdateWrapper<Event> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("plan_id", eventDto.getPlanId());
            this.remove(updateWrapper);
        } else {
            this.removeById(eventDto.getEventId());
        }
        iPlanService.deleteUnusedPlan(eventDto.getPlanId());

        return true;
    }

    @Override
    public boolean updateStatus(EventDto eventDto) {
        UpdateWrapper<Event> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", eventDto.getStatus() == 1 ? 0 : 1).eq("id", eventDto.getEventId());
        return this.update(updateWrapper);
    }

    /**
     * 保存plan，返回ID
     */
    private int savePlan(EventDto eventDto) {
        Plan plan = new Plan();
        plan.setStatus(CalendarConstant.STATUS_OK);
        plan.setTitle(eventDto.getTitle());
        plan.setCreateTime(LocalDateTime.now());
        iPlanService.save(plan);
        return plan.getId();
    }

    /**
     * 获取所有日期
     */
    private List<LocalDate> getAllDateList(LocalDate oriDate) {
        Config config = iConfigService.getOneByAppAndTypeAndCodeAndParent(CalendarConstant.APP_ID, CalendarConstant.SCT_DEFAULT, CalendarConstant.SCC_INTERVAL, CalendarConstant.PARENT_ID_TOP);
        JSONArray jsonArray = JSONUtil.parseArray(config.getValue());

        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(oriDate);

        for (Object i : jsonArray) {
            int num = Integer.valueOf(i.toString());
            dateList.add(oriDate.plusDays(num));
        }

        return dateList;
    }
}
